#include "transmit_data.h"
#include "ui_transmit_data.h"
#include <QFile>

TransmitData::TransmitData(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TransmitData)
{
    ui->setupUi(this);
}

TransmitData::~TransmitData()
{
    delete ui;
}

void TransmitData::connectToHost(QTcpSocket& tcpSocket, const QString& hostAddress, int port)
{
    tcpSocket.connectToHost(hostAddress, port);
    if (tcpSocket.waitForConnected()) {
       // qDebug() << "Connected to the host.";
    } else {
       // qDebug() << "Failed to connect to the host.";
    }
}

void TransmitData::disconnectFromHost(QTcpSocket& tcpSocket)
{
    tcpSocket.disconnectFromHost();
    if (tcpSocket.state() == QAbstractSocket::UnconnectedState ||
        tcpSocket.waitForDisconnected()) {
        qDebug() << "Disconnected from the host.";
    } else {
        qDebug() << "Failed to disconnect from the host.";
    }
}

void TransmitData::sendStringData(const QString& data)
{
    QString hostAddress = "127.0.0.1";
    int port = 8080;

    QTcpSocket tcpSocket;
    connectToHost(tcpSocket, hostAddress, port);

    if (tcpSocket.state() == QAbstractSocket::ConnectedState) {
        QByteArray dataBytes = data.toUtf8();

        uint8_t crc = crc8((uint8_t*)dataBytes.data(), dataBytes.length());
        QByteArray dataWithCRC = dataBytes +
                QByteArray::fromRawData(reinterpret_cast<const char*>(&crc), 1);
        tcpSocket.write(dataWithCRC);
        tcpSocket.waitForBytesWritten();

        disconnectFromHost(tcpSocket);
    }
}


void TransmitData::sendFileData(const QString& filePath)
{
    QString hostAddress = "127.0.0.1";
    int port = 8080;

    QTcpSocket tcpSocket;
    connectToHost(tcpSocket, hostAddress, port);

    if (tcpSocket.state() == QAbstractSocket::ConnectedState) {
        QFile file(filePath);
        if (file.open(QIODevice::ReadOnly)) {
            QByteArray fileData = file.readAll();
            file.close();

            uint8_t crc = crc8((uint8_t*)fileData.data(), fileData.size());
            QByteArray crcBytes = QByteArray::fromRawData(reinterpret_cast<const char*>(&crc), 1);

            fileData.append(crcBytes);

            qint64 bytesSent = 0;
            while (bytesSent < fileData.size()) {
                qint64 bytesToWrite = qMin(static_cast<qint64>(1024), fileData.size() - bytesSent);
                qint64 bytesWritten = tcpSocket.write(fileData.constData() + bytesSent, bytesToWrite);
                if (bytesWritten == -1) {
                    qDebug() << "Failed to write data to the socket.";
                    break;
                }

                bytesSent += bytesWritten;
            }

            tcpSocket.waitForBytesWritten();
        } else {
            qDebug() << "Failed to open the file for reading.";
        }

        disconnectFromHost(tcpSocket);
    }
}

uint8_t TransmitData::crc8(uint8_t *data, uint16_t length)
{
    uint8_t i;
    uint8_t crc = 0;
    while(length--)
    {
        crc ^= *data++;
        for ( i = 0; i < 8; i++ )
        {
            if ( crc & 0x80 )
                crc = (crc << 1) ^ 0x07;
            else
                crc <<= 1;
        }
    }
    return crc;
}
